#pragma once

#include <QMultiMap>
#include <QHostAddress>

class QTcpSocket;

class HttpRequest
{
public:
    enum RequestStatus { waitForRequest, waitForHeader, waitForBody, complete, abort };

    HttpRequest();
    ~HttpRequest();

public:
    void readFromSocket(QTcpSocket *);

    void reset();
    RequestStatus getStatus() const;
    QByteArray getMethod() const;
    const QByteArray &getRawPath() const;
    QByteArray getVersion() const;
    QByteArray getHeader(const QByteArray &name) const;
    QList<QByteArray> getHeaders(const QByteArray &name) const;
    QMultiMap<QByteArray, QByteArray> getHeaderMap() const;
    QByteArray getParameter(const QByteArray &name) const;
    QList<QByteArray> getParameters(const QByteArray &name) const;
    QMultiMap<QByteArray, QByteArray> getParameterMap() const;
    QByteArray getBody() const;

private:
    void readRequest(QTcpSocket *);
    void readHeader(QTcpSocket *);
    void readBody(QTcpSocket *);

private:
    QMultiMap<QByteArray, QByteArray>headers;
    int currentSize;
    int maxSize;
    /** Buffer for collecting characters of request and header lines */
    QByteArray lineBuffer;
    RequestStatus status;

    /** Request method */
    QByteArray method;
    /** Request path (in raw encoded format) */
    QByteArray path;
    /** Request protocol version */
    QByteArray version;
    /** Address of the connected peer. */
    QHostAddress peerAddress;

    /** Name of the current header, or empty if no header is being processed */
    QByteArray currentHeader;
    /** Boundary of multipart/form-data body. Empty if there is no such header */
    QByteArray boundary;
    /** Expected size of body */
    int expectedBodySize;
    /** Storage for raw body data */
    QByteArray bodyData;

    /** Parameters of the request */
    QMultiMap<QByteArray, QByteArray> parameters;
};
Q_DECLARE_METATYPE(HttpRequest)
